﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Security.Cryptography;
using NetworkManagement;

namespace LorraineSec.MessageLib.Messages
{
    public sealed class SymKeyExchangeMessage : EncryptedMessage
    {
        #region Format Constants
        /*
         * Format:
         *          1            1         x       y
         * | SymKey Length | IV Length | SymKey | IV | 
         * 
         */
        private const int ENC_SYMKEYLEN_LENGTH = 1;
        private const int ENC_IVLEN_LENGTH = 1;

        private const int ENC_SYMKEYLEN_OFFSET = 0;
        private const int ENC_IVLEN_OFFSET = ENC_SYMKEYLEN_OFFSET + ENC_SYMKEYLEN_LENGTH;
        private const int ENC_SYMKEY_OFFSET = ENC_IVLEN_OFFSET + ENC_IVLEN_LENGTH;

        private const int ENC_KNOWN_LENGTH = ENC_SYMKEYLEN_LENGTH + ENC_IVLEN_LENGTH;
        #endregion

        public byte[] symKey, IV;

        public SymKeyExchangeMessage()
        {
            init();
        }

        public SymKeyExchangeMessage(byte[] bytes)
            : base(bytes)
        {
            init();
            decode();
        }

        private void init()
        {
            MessageID = (ushort)LorraineSecMessageFactory.MessageID.SYMKEY_EXCHANGE;
        }

        public new void decrypt(RSACryptoServiceProvider rsa)
        {
            //Decrypt byte array
            base.decrypt(rsa);
            //Decode byte array
            symKey = Bytes.getByteArray(encData, ENC_SYMKEY_OFFSET, Bytes.getByte(encData, ENC_SYMKEYLEN_OFFSET));
            IV = Bytes.getByteArray(encData, ENC_SYMKEY_OFFSET + symKey.Length, Bytes.getByte(encData, ENC_IVLEN_OFFSET));
        }

        public new void encrypt(RSACryptoServiceProvider rsa)
        {
            //Encode byte array
            encData = new byte[ENC_KNOWN_LENGTH + symKey.Length + IV.Length];
            Bytes.setValue(encData, ENC_SYMKEYLEN_OFFSET, symKey.Length);
            Bytes.setValue(encData, ENC_IVLEN_OFFSET, IV.Length);
            Bytes.setValue(encData, ENC_SYMKEY_OFFSET, symKey);
            Bytes.setValue(encData, ENC_SYMKEY_OFFSET + symKey.Length, IV);
            //Encrypt byte array
            base.encrypt(rsa);
        }
    }
}
